package com.zhu.rtda.heap;

import com.zhu.classfile.ClassBinary;
import com.zhu.rtda.InstanceOop;
import com.zhu.rtda.Slot;
import com.zhu.rtda.heap.constant.RuntimeConstantPool;

/**
 * InstanceKlass 表示 JVM 中的运行时类结构（对应 HotSpot 的 InstanceKlass）
 * 它存储类的元数据：访问标志、父类、接口、字段、方法、常量池、静态变量等。
 * <p>
 * 该类不可直接实例化，必须通过静态工厂方法  创建。
 * </p>
 */
public class InstanceKlass {
    // region --- 字段：类的基本信息 ---
    /** 类的访问标志，如 ACC_PUBLIC, ACC_FINAL 等 */
    private int accessFlags;
    /** 类的全限定名，例如 "java/lang/Object" */
    private String name;
    /** 父类的全限定名，例如 "java/lang/Number" */
    private String superClassName;
    /** 实现的接口全限定名数组 */
    private String[] interfaceNames;
    // endregion

    // region --- 字段：类的组成部分 ---
    /** 运行时常量池 */
    private RuntimeConstantPool constantPool;
    /** 字段数组 */
    private Field[] fields;
    /** 方法数组
     * JVM 的类加载行为（标准实现）：
     * 每个类的 methods 字段（即 Method[] methods）只包含该类自己定义的方法（包括显式声明、隐式生成的 <init>、<clinit> 等）。
     * 不会自动复制父类的方法到子类的 methods 数组中。
     * */
    private Method[] methods;
    // endregion

    // region --- 字段：运行时链接 ---
    /** 加载该类的类加载器 */
    private ClassLoader classLoader;
    /** 父类的运行时类对象 */
    private InstanceKlass superClass;
    /** 实现的接口的运行时类对象数组 */
    private InstanceKlass[] interfaces;
    // endregion

    // region --- 字段：内存布局 ---
    /** 实例变量槽位总数（包括父类继承的） */
    private int instanceSlotCount;
    /** 静态变量槽位总数 */
    private int staticSlotCount;
    /** 静态变量存储区 */
    private Slot[] staticVars;
    // endregion

    // region --- 私有构造函数 ---
    private InstanceKlass() {
        // 初始化在 fromClassBinary 中完成
    }
    // endregion

    // region --- 静态工厂方法 ---
    /**
     * 从 ClassBinary（.class 文件解析结果）创建 InstanceKlass 实例。
     * 这是创建 InstanceKlass 的唯一入口。
     *
     * @param classBinary .class 文件的二进制解析结果
     * @return 构建好的 InstanceKlass 对象
     */
    public static InstanceKlass fromClassBinaryToInstanceKlass(ClassBinary classBinary) {
        InstanceKlass klass = new InstanceKlass();

        klass.accessFlags = classBinary.getAccessFlags();
        klass.name = classBinary.getClassName();
        klass.superClassName = classBinary.getSuperClassName();
        klass.interfaceNames = classBinary.getInterfaceNames();

        klass.constantPool = RuntimeConstantPool.creteRuntimeConstantPool(klass, classBinary.getConstantPool());
        klass.fields = Field.newFields(klass, classBinary.getFields());
        klass.methods = Method.newMethods(klass, classBinary.getMethods());

        // 初始化槽位计数
        klass.instanceSlotCount = 0;
        klass.staticSlotCount = 0;

        return klass;
    }
    // endregion

    // region --- Getter 方法 ---
    public int getAccessFlags() { return accessFlags; }
    public String getName() { return name; }
    public String getSuperClassName() { return superClassName; }
    public String[] getInterfaceNames() { return interfaceNames; }
    public RuntimeConstantPool getConstantPool() { return constantPool; }
    public Field[] getFields() { return fields; }
    public Method[] getMethods() { return methods; }
    public ClassLoader getClassLoader() { return classLoader; }
    public InstanceKlass getSuperClass() { return superClass; }
    public InstanceKlass[] getInterfaces() { return interfaces; }
    public int getInstanceSlotCount() { return instanceSlotCount; }
    public int getStaticSlotCount() { return staticSlotCount; }
    public Slot[] getStaticVars() { return staticVars; }


    // endregion

    // region --- Setter 方法 ---
    public void setAccessFlags(int accessFlags) {
        this.accessFlags = accessFlags;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setSuperClassName(String superClassName) {
        this.superClassName = superClassName;
    }

    public void setInterfaceNames(String[] interfaceNames) {
        this.interfaceNames = interfaceNames;
    }

    public void setConstantPool(RuntimeConstantPool constantPool) {
        this.constantPool = constantPool;
    }

    public void setFields(Field[] fields) {
        this.fields = fields;
    }

    public void setMethods(Method[] methods) {
        this.methods = methods;
    }
    public void setClassLoader(ClassLoader classLoader) { this.classLoader = classLoader; }
    public void setSuperClass(InstanceKlass superClass) { this.superClass = superClass; }
    public void setInterfaces(InstanceKlass[] interfaces) { this.interfaces = interfaces; }
    public void setInstanceSlotCount(int instanceSlotCount) { this.instanceSlotCount = instanceSlotCount; }
    public void setStaticSlotCount(int staticSlotCount) { this.staticSlotCount = staticSlotCount; }
    public void setStaticVars(Slot[] staticVars) { this.staticVars = staticVars; }
    // endregion

    // region --- 访问标志判断（使用你的 AccessFlags 枚举） ---
    public boolean isPublic()     { return AccessFlags.ACC_PUBLIC.isSetIn(accessFlags); }
    public boolean isFinal()      { return AccessFlags.ACC_FINAL.isSetIn(accessFlags); }
//    public boolean isSuper()      { return AccessFlags.ACC_SUPER.isSetIn(accessFlags); }
    public boolean isInterface()  { return AccessFlags.ACC_INTERFACE.isSetIn(accessFlags); }
    public boolean isAbstract()   { return AccessFlags.ACC_ABSTRACT.isSetIn(accessFlags); }
    public boolean isSynthetic()  { return AccessFlags.ACC_SYNTHETIC.isSetIn(accessFlags); }
//    public boolean isAnnotation() { return AccessFlags.ACC_ANNOTATION.isSetIn(accessFlags); }
    public boolean isEnum()       { return AccessFlags.ACC_ENUM.isSetIn(accessFlags); }
    // endregion

    // region --- 类加载可见性 ---
    public boolean isAccessibleTo(InstanceKlass other) {
        return this.isPublic() || getPackageName().equals(other.getPackageName());
    }

    public String getPackageName() {
        int lastSlash = name.lastIndexOf('/');
        if (lastSlash >= 0) {
            return name.substring(0, lastSlash);
        }
        return "";
    }
    // endregion

    // region --- 特殊方法查找 ---
    public Method getMainMethod() {
        return getStaticMethod("main", "([Ljava/lang/String;)V");
    }

    private Method getStaticMethod(String name, String descriptor) {
        for (Method method : methods) {
            if (method.isStatic() &&
                    method.getName().equals(name) &&
                    method.getDescriptor().equals(descriptor)) {
                return method;
            }
        }
        return null;
    }
    // endregion

    // region --- 实例创建 ---
    public InstanceOop newObject() {
        return new InstanceOop(this);
    }
    // endregion

    /**
     * 判断当前类是否是指定类的子类（直接或间接继承）
     *
     * @param other 父类
     * @return 是否为子类
     */
    public boolean isSubClassOf(InstanceKlass other) {
        if (other == null) return false;
        InstanceKlass c = this.superClass;
        while (c != null) {
            if (c == other) {
                return true;
            }
            c = c.superClass;
        }
        return false;
    }

    // region --- 类型兼容性检查（对应 Go 中的 Class 方法） ---

    /**
     * 实际语义：other是否是 当前类（this） 的子类型（包括实现、继承、相同）
     */
    public boolean isAssignableFrom(InstanceKlass other) {
        if (other == null) {
            return false;
        }
        // s = other, t = this
        //t是instanceof 指令后面的操作数解析出来的类
        //s实际上是对象中的运行时类的引用
        InstanceKlass s = other;
        InstanceKlass t = this;

        if (s == t) {
            return true;
        }

        if (!t.isInterface()) {
            // t 是类，则 s 必须是 t 的子类
            return s.isSubClassOf(t);
        } else {
            // t 是接口，则 s 必须实现 t
            return s.isImplements(t);
        }
    }

    /**
     * 判断当前类（this）是否实现了指定接口（iface）
     * 支持通过父类或自身实现接口
     */
    public boolean isImplements(InstanceKlass iface) {
        if (!iface.isInterface()) {
            return false; // 安全防护：传入的必须是接口
        }

        // 从当前类开始，沿继承链向上查找
        for (InstanceKlass c = this; c != null; c = c.superClass) {
            // 检查 c 直接实现的接口
            for (InstanceKlass i : c.interfaces) {
                if (i == iface || i.isSubInterfaceOf(iface)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 判断当前接口（this）是否是 iface 的子接口（直接或间接继承）
     */
    public boolean isSubInterfaceOf(InstanceKlass iface) {
        if (!this.isInterface() || !iface.isInterface()) {
            return false;
        }

        for (InstanceKlass superInterface : this.interfaces) {
            if (superInterface == iface || superInterface.isSubInterfaceOf(iface)) {
                return true;
            }
        }
        return false;
    }

}
